package com.robot.mvvm.vm.login

import android.app.Application
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.databinding.ObservableField
import api.UserServiceFactory
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.StringUtils
import com.blankj.utilcode.util.ToastUtils
import com.robot.base.base.vm.GLBaseViewModel
import com.robot.base.common.api.AbstractViewModelSubscriber
import com.robot.base.configs.AppConstants
import com.robot.base.configs.PrefsManager
import com.robot.base.model.LoginBean
import com.robot.base.util.Util
import com.robot.base.util.arouter.ARouterUtil
import com.robot.base.utils.JobUtil
import com.robot.mvvm.GlApp
import com.robot.mvvm.R
import kotlinx.coroutines.Job
import me.goldze.mvvmhabit.binding.command.BindingAction
import me.goldze.mvvmhabit.binding.command.BindingCommand
import me.goldze.mvvmhabit.binding.command.BindingConsumer
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent
import me.goldze.mvvmhabit.http.BaseResponse
import okhttp3.ResponseBody
import java.io.InputStream

class LoginViewModel(application: Application) : GLBaseViewModel(application) {
    val type = ObservableField<Boolean>(true)
    val promptSelect = ObservableField(false)
    val number = ObservableField<String>()
    val name = ObservableField<String>()
    val password = ObservableField<String>()
    val code = ObservableField<String>()
    var codeImg: InputStream? = null

    val uc = UiChangeEvent()

    class UiChangeEvent {
        val typeEvent = SingleLiveEvent<Boolean>()
        val codeEvent = SingleLiveEvent<Void>()
    }

    init {
        promptSelect.set(GlApp.checkProtocol)
    }

    fun start() {
        startGetCode()
        getCode()
    }

    val userCommand = BindingCommand<Any>(BindingAction {
        type.set(true)
        uc.typeEvent.postValue(true)
    })

    val operationCommand = BindingCommand<Any>(BindingAction {
        type.set(false)
        uc.typeEvent.postValue(false)
    })

    val promptClick = BindingCommand<Any>(BindingAction {
        promptSelect.set(!promptSelect.get()!!)
        GlApp.checkProtocol = promptSelect.get() ?: false
    })

    val getCodeCommand = BindingCommand<Any>(BindingAction {
        getCodeJob?.cancel()
        startGetCode()
        getCode()

    })
    val confirmCommand = BindingCommand<Any>(BindingAction {
        if (checkPrompt())
            return@BindingAction
        login()
    })

    private fun checkPrompt(): Boolean {
        if (promptSelect.get() == false) {
            ToastUtils.showShort(StringUtils.getString(R.string.app_error_1))
        }
        return promptSelect.get() == false
    }

    var getCodeJob: Job? = null
    private fun startGetCode() {
        if (getCodeJob == null)
            getCodeJob = JobUtil.countUpCoroutines(60000,
                {
                    getCode()
                    startGetCode()
                },
                {

                }
            )
        if (getCodeJob?.isActive == false) {
            getCodeJob?.start()
        }
    }

    private fun getCode() {
        UserServiceFactory.getCode(PrefsManager.getUUid()).subscribe(
            object : AbstractViewModelSubscriber<ResponseBody>(this) {
                override fun onNext(t: ResponseBody) {
                    codeImg = t.byteStream()
                    uc.codeEvent.call()
                }
            }
        )
    }

    private fun login() {
        showLoadingDialog()
        val passwordAES = Util.encryptAES(password.get() ?: "", "1234567890ABCDEF")
        LogUtils.e(passwordAES)
        UserServiceFactory.login(
            mapOf(
                "belongType" to if (type.get() == true) {
                    "1"
                } else {
                    "0"
                },
                "isEncrypted" to true,
                "tenantNo" to number.get(),
                "username" to name.get(),
                "password" to passwordAES,
                "captchaCode" to code.get(),
                "clientType" to "1"
            )
        ).subscribe(object : AbstractViewModelSubscriber<BaseResponse<LoginBean>>(this) {
            override fun onNext(t: BaseResponse<LoginBean>) {
                dismissLoadingDialog()
                PrefsManager.saveUserLoginInfo(t.data)
                ARouterUtil.goToActivity(AppConstants.Router.Main.A_MAIN)
            }
        })
    }
}